#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os

from common import common
from common.common_models import CopyInfoRepModel, Copy
from common.const import RepositoryDataTypeEnum, RepoProtocalType
from common.logger import Logger
from common.parse_parafile import ParamFileUtil
from db2.backup.util.dpf_backup_util import DpfBackupUtil
from db2.comm.const import Db2CommonConst, RpcToolApiName
from db2.comm.util.common_util import Db2CommonUtil

LOGGER = Logger().get_logger(filename="db2.log")


class DpfTsBackupService:
    @staticmethod
    def create_backup_dir(os_user, backup_dir):
        Db2CommonUtil.check_path_list(backup_dir)
        if os_user and not os.path.exists(backup_dir):
            os.mkdir(backup_dir)
            user_id = Db2CommonUtil.get_os_user_id_by_os_user(os_user)
            group_id = Db2CommonUtil.get_group_id_by_os_user(os_user)
            LOGGER.info(f"Create backup dir and change owner, os user: {os_user}, "
                        f"user id: {user_id}, group id: {group_id}.")
            os.lchown(backup_dir, user_id, group_id)

    @staticmethod
    def exec_full_backup_ts(os_user, db_name, ts_names, backup_dir):
        ts_names_str = ",".join(ts_names)
        ts_full_bak_cmd = f'su - {os_user} -c "db2 backup db {db_name} on all nodes tablespace \({ts_names_str}\) ' \
                          f'online to {backup_dir}"'
        Db2CommonUtil.check_injection(os_user, db_name, ts_names_str)
        backup_time = DpfBackupUtil.execute_ts_backup(ts_full_bak_cmd)
        return backup_time

    @staticmethod
    def exec_incr_backup_ts(os_user, db_name, ts_names, backup_dir):
        ts_names_str = ",".join(ts_names)
        ts_incr_bak_cmd = f'su - {os_user} -c "db2 backup db {db_name} on all nodes tablespace \({ts_names_str}\) ' \
                          f'online incremental delta to {backup_dir}"'
        Db2CommonUtil.check_injection(os_user, db_name, ts_names_str)
        backup_time = DpfBackupUtil.execute_ts_backup(ts_incr_bak_cmd)
        return backup_time

    @staticmethod
    def exec_diff_backup_ts(os_user, db_name, ts_names, backup_dir):
        ts_names_str = ",".join(ts_names)
        ts_diff_bak_cmd = f'su - {os_user} -c "db2 backup db {db_name} on all nodes tablespace \({ts_names_str}\) ' \
                          f'online incremental to {backup_dir}"'
        Db2CommonUtil.check_injection(os_user, db_name, ts_names_str)
        backup_time = DpfBackupUtil.execute_ts_backup(ts_diff_bak_cmd)
        return backup_time

    @staticmethod
    def query_copy_repos_after_backup(job_id, param_dict, backup_type):
        backup_dir_prefix = Db2CommonConst.BACKUP_TYPE_DIR_PREFIX_MAP.get(backup_type)
        copy_path = f'{backup_dir_prefix}_{job_id}'
        copy_repo_info = ParamFileUtil.get_rep_info(
            param_dict.get("job"), RepositoryDataTypeEnum.DATA_REPOSITORY.value)
        remote_path = os.path.realpath(os.path.join(copy_repo_info.get('remotePath'), copy_path))
        repo_models = [
            CopyInfoRepModel(
                id=copy_repo_info.get('id'), repositoryType=copy_repo_info.get("repositoryType"),
                isLocal=copy_repo_info.get("isLocal"), protocol=RepoProtocalType.NFS.value,
                remotePath=remote_path, remoteHost=copy_repo_info.get("remoteHost"),
                extendInfo=copy_repo_info.get('extendInfo')
            )
        ]
        return repo_models

    @staticmethod
    def abort_ts_backup_job(user_name, db_name):
        return True
